
import os, argparse
from tomlkit import loads
from tomlkit import dump

def nest_dictionary(d, keys, val):
    for key in keys:
        d = d.setdefault(key, val)
    return d

class MicroblogConfig:
    def __init__(self, given_config):
        self.is_outdated = False
        self.updated = given_config

    def compare(self, sref, suser, keylist=[]):
        # subtable of ref, subtable of user
        updated = self.updated
        # nnavigate to table
        if keylist != []:
            for key in keylist:
                sref = sref[key]
            for key in keylist:
                suser = suser[key]
            for key in keylist:
                updated = updated[key]
        for key in sref:
            if key not in suser:
                self.is_outdated = True
                updated[key] =sref[key]
                print("noticed '", key, "' missing from ", keylist)
        nest_dictionary(self.updated, keylist, updated)
        return

    def check(self, r, u): # (reference, user)
        for key in r:
            if key == "latestpages": continue;
            # post and webring have subtables
            #   webring.profile
            #   webring.following
            #   webring.following.internal-avatars
            #   post.gallery
            #   post.buttons
            try:
                self.compare(r, u, [key])
            except KeyError:
                u[key] = dict()
                print("missing top-level table '", key, '\'')
                self.compare(r, u, [key])
            if key == "webring":
                self.compare(r, u, ["webring", "profile"])
                self.compare(r, u, ["webring", "following"])
                self.compare(r, u, ["webring", "following", "internal-avatars"])
            if key == "post":
                self.compare(r, u, ["post", "gallery"])
                self.compare(r, u, ["post", "buttons"])
        pass

def load_files(user_conf_file):
    script_dir = os.path.dirname(
        os.path.abspath(__file__))
    parent_dir = os.path.abspath(
        os.path.join(script_dir, os.pardir))
    target_folder = "example"
    example = os.path.abspath(
        os.path.join(parent_dir, target_folder))
    ref_file = "%s/%s" % (example, "/settings.toml")
    if not os.path.exists(ref_file):
        return
    ref_conf = dict()
    with open(ref_file, 'r') as f:
        ref_conf = loads(f.read())
    user_conf = dict()
    with open(user_conf_file, 'r') as f:
        user_conf = loads(f.read())
    return ref_conf, user_conf

def multi_prompt(message):
    try:
        while True:
            user_input = int(input(f"{message}").lower())
            if  user_input < 3:
                return user_input
            else:
                return 0
    except KeyboardInterrupt:
        print()
    except ValueError:
        pass
    return 0

def get_args():
    p = argparse.ArgumentParser()
    p.add_argument("--no-prompt", action="store_true", \
        help="does not ask what to do if missing keys are detected")
    p.add_argument("-c", "--check", type=str,\
        help="sets/changes the file to be checked (default: settings.toml)")
    args = p.parse_args()
    if args.no_prompt:
        print("'--no-prompt' set")
    if args.check:
        print("--check set", args.check)
    else:
        args.check = "settings.toml"
    return args.no_prompt, args.check

def main(is_no_prompt, user_conf_file="settings.toml"):
    print("checking ", user_conf_file)
    reference, user_edited = load_files(user_conf_file)
    mcfg = MicroblogConfig(user_edited)
    mcfg.check(reference, user_edited)
    if mcfg.is_outdated == False:
        print("Your settings file is OK!")
        return
    message = """
    Your settings file is outdated.
    Do you want to...
    \t 1. save new settings to new file
    \t 2. update/overwrite existing settings
    \t *. do nothing
    """
    response = 0 if is_no_prompt else multi_prompt(message)
    out_file = str()
    if response == 0:
        return
    elif response == 1:
        out_file = "new.toml"
    elif response == 2:
        out_file = user_conf_file
    with open(out_file, 'w') as f:
        dump(mcfg.updated, f)
    print("Wrote updated config to ", out_file)
    pass

if __name__ == "__main__":
    main(*get_args())
